/**
 * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
 */
package com.kylin.common.weixin.util;

import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.entity.mime.FileBody;
import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
import org.apache.hc.client5.http.entity.mime.StringBody;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
import org.apache.hc.client5.http.ssl.NoopHostnameVerifier;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.ssl.SSLContexts;
import org.apache.hc.core5.ssl.TrustStrategy;
import org.apache.hc.core5.util.Timeout;
import org.apache.http.Consts;

import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;

/**
 * HTTP客户端工具类（支持HTTPS）
 * @author ThinkGem
 * @version 2017-3-27
 */
public class HttpUtils {

	public static CloseableHttpClient httpClient = HttpClients.createDefault();

	static {
		// 设置超时时间
		RequestConfig config = RequestConfig.custom().setConnectTimeout(Timeout.ofMilliseconds(60000L))
				.setConnectionRequestTimeout(Timeout.ofMilliseconds(60000L))
				.setResponseTimeout(Timeout.ofMilliseconds(60000L)).build();
		// httpclient5经测试不设置支持ssl，也能调用https接口
		try {
			httpClient = HttpClients.custom().setDefaultRequestConfig(config)
					.setConnectionManager(getHttpClientConnectionManager()).build();
		} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
			httpClient = HttpClients.createDefault();
			e.printStackTrace();
		}

	}

	private static HttpClientConnectionManager getHttpClientConnectionManager()
			throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
		// 设置连接池最大连接数1000,最大并发数200，及支持ssl,tls
		return PoolingHttpClientConnectionManagerBuilder.create().setMaxConnTotal(1000).setMaxConnPerRoute(200)
				.setSSLSocketFactory(getSslConnectionSocketFactory()).build();
	}

	/**
	 * 支持SSL
	 *
	 * @return SSLConnectionSocketFactory
	 */
	private static SSLConnectionSocketFactory getSslConnectionSocketFactory()
			throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
		TrustStrategy acceptingTrustStrategy = (x509Certificates, s) -> true;
		SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
		return new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());
		//链接tls版本协议，不指定也可以
//		return new SSLConnectionSocketFactory(sslContext,  new String[] {"TLSv1.1","TLSv1.2","TLSv1.3"},
//				  null, new NoopHostnameVerifier());

	}

	public static String upload(String url, File file, Map<String, String> dataMap) {
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		try {
			httpClient = HttpClients.createDefault();
			HttpPost httpPost = new HttpPost(url);

			MultipartEntityBuilder reqEntityBuilder = MultipartEntityBuilder.create();
			if (dataMap != null){
				for (Map.Entry<String, String> entry : dataMap.entrySet()) {
					reqEntityBuilder.addPart(entry.getKey(),new StringBody(entry.getValue(), ContentType.create(
							"text/plain", Consts.UTF_8)));
				}
			}
			// 把文件转成流对象FileBody
			FileBody bin = new FileBody(file);
			reqEntityBuilder.addPart("file", bin);
			httpPost.setEntity(reqEntityBuilder.build());


			// 发起请求
			response = httpClient.execute(httpPost);

			// 获取响应对象
			HttpEntity resEntity = response.getEntity();
			if (resEntity != null) {
				// 打印响应长度
				System.out.println("Response content length: " + resEntity.getContentLength());
				// 打印响应内容
				System.out.println(EntityUtils.toString(resEntity, Charset.forName("UTF-8")));
				return EntityUtils.toString(resEntity, Charset.forName("UTF-8"));
			}

			// 销毁
			EntityUtils.consume(resEntity);
		}catch (Exception e) {
			e.printStackTrace();;
		}finally {
			try {
				if(response != null){
					response.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}

			try {
				if(httpClient != null){
					httpClient.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return "";
	}



}
